#ifndef BOUNDARY_RADIANCE_TRANSFER_H
#define BOUNDARY_RADIANCE_TRANSFER_H

#include <G3D/G3DAll.h>
#include "FlowSolver.h"
#include "SphericalHarmonics.h"

struct Photon
{
public:
	float rad;
	Vector3 pos, dir;

public:
	Photon()
	{
		rad = 1.0f;
	}
};

class VolumeRadianceTransfer
{
public:
	int lmax, psamples, rsamples, pbands, rbands;
	float siga, sigs, minrad, maxrad;
	PointKDTree<Photon> kdtree;
	Array<SHFunction<float>> bndrad[6];	// current radiance
	SHFunction<float> lighting;
	//VertexBufferRef vbo;
	//VertexRange vb;
	//VertexRange nb;
	//ShaderRef pshader;

public:
	VolumeRadianceTransfer();

public:
	void tracePhotons(const Field<float> &field, int l, int m);
	float estimateRadiance(const Field<float> &field, const Ray &ray, const Vector3 &boxMin, const Vector3 &boxMax);
	void estimateRadianceSH(const Field<float> &field, const Vector3 &pos, SHFunction<float> &sh);
	void renderScattering(const Field<float> &field, const Vector3 &boxMin, const Vector3 &boxMax, const GCamera &camera, Image1::Ref image);
	float sampleBoundaryRadiance(const Array<SHFunction<float>> &rad, int pitch, const Vector2 &pos, const Vector3 &dir);
	float sampleBoundaryRadiance(const Field<float> &field, const Ray &ray, const Vector3 &boxMin, const Vector3 &boxMax);
	void render(const Field<float> &field, const Vector3 &boxMin, const Vector3 &boxMax, const GCamera &camera, Image1::Ref image);
	//void tracePhotons(Field<float> &field, bool append);
	//void updateVertexBuffer();
	void evaluateLightField(Field<float> &light);
	void renderVertexBuffer(RenderDevice *rd, const Vector3 &offset, const Vector3 &scale);
};

#endif
